#include "../include/CBoatEnemyBehaviour.h"
#include "../include/CDefaultShotBehaviour.h"
#include "../include/CBombShotBehaviour.h"
#include "../include/CSprite.h"
#include "../include/CSpriteAnimation.h"

#include <SDL/SDL.h>
#include <math.h>

//**************************
//Description : Constructor
//Parameters : Value for m_iX, m_iY,
//              m_iSpeedX, m_iSpeedY,
//              m_iWidth, m_iHeight,
//              the ratio for the collision box
//              the type of colision
//              m_iLives
//              m_iNbPoints
//Note : None
//**************************
CBoatEnemyBehaviour::CBoatEnemyBehaviour(int _iX, int _iY,
                                                int _iSpeedX, int _iSpeedY,
                                                int _iWidth, int _iHeight,
                                                float _fRatioW, float _fRatioH,
                                                TYPE_COLLISION _iTypeCollision,
                                                int _iLives,
                                                int _iNbPoints)
    : CDefaultEnemyBehaviour(_iX, _iY,
                                _iSpeedX, _iSpeedY,
                                _iWidth, _iHeight,
                                _fRatioW, _fRatioW,
                                _iTypeCollision,
                                _iLives,
                                _iNbPoints)
{
    //this enemy only have a primary shot
    m_iPrimaryShot = DEFAULTSHOT;
    m_iSecondaryShot = -1;

    m_iTimeBetweenPrimaryShot = 800;
    m_iTimeBetweenSecondaryShot = -1;
}

//**************************
//Description : Copy Constructor
//Parameters : A CBoatEnemyBehaviour
//Note : None
//**************************
CBoatEnemyBehaviour::CBoatEnemyBehaviour(CBoatEnemyBehaviour & _BoatEnemy)
    : CDefaultEnemyBehaviour(_BoatEnemy)
{
}

//**************************
//Description : Destructor
//Parameters : None
//Note : None
//**************************
CBoatEnemyBehaviour::~CBoatEnemyBehaviour()
{
}

//**************************
//Description : The entity shoot
//Parameters : The tab of animations shot and the screen
//Return Value : True if the enemy has shot, otherwise false
//Note : Virtual because the way of shooting depends on the entity
//**************************
bool CBoatEnemyBehaviour::Shoot(CSpriteAnimation * _SpriteAnimationShot, SDL_Surface * _screen)
{
    if ( ( (Uint32)(m_lLastPrimaryShoot + m_iTimeBetweenPrimaryShot) < SDL_GetTicks() ) )
    {
        CDefaultShotBehaviour * Shot;

        switch ( m_iPrimaryShot )
        {
            case DEFAULTSHOT:
            {
                //upper right side
                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                0,
                                                -4,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                1,
                                                -4,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                2,
                                                -4,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                3,
                                                -3,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                4,
                                                -2,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                4,
                                                -1,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                //lower right side
                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                4,
                                                0,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                4,
                                                1,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                4,
                                                2,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                3,
                                                3,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                2,
                                                4,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                1,
                                                4,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                //upper left side
                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                -1,
                                                -4,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                -2,
                                                -4,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                -3,
                                                -3,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                -4,
                                                -2,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                -4,
                                                -1,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                //lower left side
                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                -4,
                                                0,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                -4,
                                                1,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                -4,
                                                2,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                -3,
                                                3,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                -2,
                                                4,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                -1,
                                                4,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                Shot = new CDefaultShotBehaviour(m_iX,
                                                m_iY,
                                                0,
                                                4,
                                                _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );

                break;
            }
            case BOMB:
            {
                //upper right side
                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                0,
                                                -4,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                1,
                                                -4,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                2,
                                                -4,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                3,
                                                -3,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                4,
                                                -2,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                4,
                                                -1,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                //lower right side
                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                4,
                                                0,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                4,
                                                1,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                4,
                                                2,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                3,
                                                3,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                2,
                                                4,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                1,
                                                4,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                //upper left side
                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                -1,
                                                -4,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                -2,
                                                -4,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                -3,
                                                -3,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                -4,
                                                -2,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                -4,
                                                -1,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                //lower left side
                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                -4,
                                                0,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                -4,
                                                1,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                -4,
                                                2,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                -3,
                                                3,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                -2,
                                                4,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                -1,
                                                4,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                Shot = new CBombShotBehaviour(m_iX,
                                                m_iY,
                                                0,
                                                4,
                                                _SpriteAnimationShot[BOMB].GetWidth(),
                                                _SpriteAnimationShot[BOMB].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[BOMB], _screen );

                m_vShots->push_back( Shot );

                break;
            }
            default:
            {
                Shot = new CDefaultShotBehaviour(m_iX, m_iY,
                                                    0, 4,
                                                    _SpriteAnimationShot[DEFAULTSHOT].GetWidth(),
                                                    _SpriteAnimationShot[DEFAULTSHOT].GetHeight());

                Shot->SetSprite( &_SpriteAnimationShot[DEFAULTSHOT], _screen );

                m_vShots->push_back( Shot );
            }
        }

        m_lLastPrimaryShoot = SDL_GetTicks();

        return true;
    }
    else
        return false;
}

//**************************
//Description : Update the trajectory of the entity
//Parameters : None
//Return Value : None
//Note : Virtual because actions depends on the entity type
//**************************
void CBoatEnemyBehaviour::EntityTrajectory()
{
    //we move on Y
    m_iY += m_iSpeedY;
}
